﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PAT.Entities;
using PAT.Services;
using PAT.Data.Bases;
using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography;

namespace PAT.MembershipProvider
{
    /// <summary>
    /// Clase que implementa una proveedor de membresias de seguridad personalizado de acuerdo al modelo establecido para la aplicación
    /// </summary>
    public class PATMembershipProviderClass : System.Web.Security.MembershipProvider
    {
        #region Atributos
        /// <summary>
        /// Proveedor de servicios que permite accesar a la funcionalidad de usuarios
        /// </summary>
        private PatUsuarioService usuarioService = new PatUsuarioService();
        #endregion

        #region SobreEscritura de propiedades de inicialización
        /// <summary>
        /// Sobreescritura de propiedad Name
        /// </summary>
        public override string Name
        {
            get { return base.Name; }            
        }

        /// <summary>
        /// Sobreescritura del metodo de inicialización
        /// </summary>
        /// <param name="name"></param>
        /// <param name="config"></param>
        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize((name != String.Empty ? name : "PATMembershipProvider"), config);
        }
        #endregion

        /// <summary>
        /// Nombre de aplicacion que usa el proveedor
        /// </summary>
        public override string ApplicationName
        {
            get;set;
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            // Se parte de la premisa que el password en la base de datos se encuentra encriptado,y el que viaja como parametro no
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            filtro.AppendEquals(PatUsuarioColumn.Login, username);
            filtro.AppendEquals(PatUsuarioColumn.Activo, true.ToString());
            TList<PatUsuario> usuarioPorLogin = usuarioService.Find(filtro.GetParameters());
            if (usuarioPorLogin.Count == 1)
            {
                if (Cryptographer.DecryptSymmetric("RijndaelManaged", usuarioPorLogin[0].Password) == oldPassword)
                {
                    usuarioPorLogin[0].Password = Cryptographer.EncryptSymmetric("RijndaelManaged", newPassword);
                    return usuarioService.Update(usuarioPorLogin[0]);
                }
            }
            return false;
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            filtro.AppendEquals(PatUsuarioColumn.Login, username);
            filtro.AppendEquals(PatUsuarioColumn.Activo, true.ToString());
            TList<PatUsuario> usuarioPorLogin = usuarioService.Find(filtro.GetParameters());
            if (usuarioPorLogin.Count == 1)
            {
                usuarioPorLogin[0].Activo = false;
                return usuarioService.Update(usuarioPorLogin[0]);
            }
            return false;
        }

        public override bool EnablePasswordReset
        {
            get { return false; }
        }

        public override bool EnablePasswordRetrieval
        {
            get { return false; }
        }

        public override System.Web.Security.MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            filtro.AppendEquals(PatUsuarioColumn.EMail, emailToMatch);
            TList<PatUsuario> usuarioPorEmail = usuarioService.Find(filtro.GetParameters(), String.Empty, pageIndex, pageSize, out totalRecords);
            System.Web.Security.MembershipUserCollection salida = new System.Web.Security.MembershipUserCollection();
            foreach (PatUsuario instancia in usuarioPorEmail)
            {
                salida.Add(new System.Web.Security.MembershipUser(String.Empty,instancia.Login,null,instancia.EMail,String.Empty,String.Empty,true,false,DateTime.Now,DateTime.Now,DateTime.Now,DateTime.Now,DateTime.Now));
            }
            return salida;
        }

        public override System.Web.Security.MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            filtro.AppendEquals(PatUsuarioColumn.Login, usernameToMatch);
            TList<PatUsuario> usuarioPorEmail = usuarioService.Find(filtro.GetParameters(), String.Empty, pageIndex, pageSize, out totalRecords);
            System.Web.Security.MembershipUserCollection salida = new System.Web.Security.MembershipUserCollection();
            foreach (PatUsuario instancia in usuarioPorEmail)
            {
                salida.Add(new System.Web.Security.MembershipUser(String.Empty, instancia.Login, null, instancia.EMail, String.Empty, String.Empty, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now));
            }
            return salida;
        }

        public override System.Web.Security.MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            TList<PatUsuario> usuarioPorEmail = usuarioService.Find(null, String.Empty, pageIndex, pageSize, out totalRecords);
            System.Web.Security.MembershipUserCollection salida = new System.Web.Security.MembershipUserCollection();
            foreach (PatUsuario instancia in usuarioPorEmail)
            {
                salida.Add(new System.Web.Security.MembershipUser(String.Empty, instancia.Login, null, instancia.EMail, String.Empty, String.Empty, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now));
            }
            return salida;
        }

        public override int GetNumberOfUsersOnline()
        {
            return 0;
        }

        public override string GetPassword(string username, string answer)
        {
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            filtro.AppendEquals(PatUsuarioColumn.Login, username);
            TList<PatUsuario> usuarioPorLogin = usuarioService.Find(filtro.GetParameters());
            if (usuarioPorLogin.Count > 0)
                return Cryptographer.DecryptSymmetric("RijndaelManaged", usuarioPorLogin[0].Password);
            else
                return String.Empty;
        }

        public override System.Web.Security.MembershipUser GetUser(string username, bool userIsOnline)
        {
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            filtro.AppendEquals(PatUsuarioColumn.Login, username);
            TList<PatUsuario> usuarioPorLogin = usuarioService.Find(filtro.GetParameters());
            if (usuarioPorLogin.Count > 0)
                return new System.Web.Security.MembershipUser(String.Empty,username,null,usuarioPorLogin[0].EMail,String.Empty,String.Empty,true,false,DateTime.Now,DateTime.Now,DateTime.Now,DateTime.Now,DateTime.Now);
            else
                return null;
        }

        public override System.Web.Security.MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override string GetUserNameByEmail(string email)
        {
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            filtro.AppendEquals(PatUsuarioColumn.EMail, email);
            TList<PatUsuario> usuarioPorEmail = usuarioService.Find(filtro.GetParameters());
            if (usuarioPorEmail.Count > 0)
                return usuarioPorEmail[0].Login;
            else
                return String.Empty;
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { return -1; }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { return -1; }
        }

        public override int MinRequiredPasswordLength
        {
            get { return -1; }
        }

        public override int PasswordAttemptWindow
        {
            get { return -1; }
        }        

        public override bool RequiresUniqueEmail
        {
            get { return true; }
        }                        

        public override bool ValidateUser(string username, string password)
        {
            PatUsuarioParameterBuilder filtro = new PatUsuarioParameterBuilder();
            filtro.AppendEquals(PatUsuarioColumn.Login, username);
            TList<PatUsuario> usuarioPorLogin = usuarioService.Find(filtro.GetParameters());
            if (usuarioPorLogin.Count == 1)
            {
                return Cryptographer.DecryptSymmetric("RijndaelManaged", usuarioPorLogin[0].Password) == password;
            }
            else
                return false;
        }

        #region Funciones No Implementadas
        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }

        public override System.Web.Security.MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out System.Web.Security.MembershipCreateStatus status)
        {
            throw new NotImplementedException();
        }

        public override System.Web.Security.MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(System.Web.Security.MembershipUser user)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}
